		TITLE	CVTYPES - Copyright (c) SLR Systems 1994

		INCLUDE	MACROS

if	fg_cvpack

		INCLUDE	CVTYPES

		PUBLIC	PROCESS_CV_TYPES


		.DATA

		EXTERNDEF	TEMP_RECORD:BYTE,CV_SPECIAL_BLOCK:DWORD

		EXTERNDEF	EXETABLE:DWORD,FIX2_SM_LEN:DWORD,MODULE_LTYPE_DELTA:DWORD

		EXTERNDEF	CV_LTYPE_GARRAY:STD_PTR_S,CV_LFWD_GARRAY:DWORD,CV_LTYPE_STUFF:ALLOCS_STRUCT

                .CODE	PASS2_TEXT
                EXTERNDEF	_get_large_segment:proc,_release_large_segment:proc

		.CODE	CVPACK_TEXT

		EXTERNDEF	CV_LTYPE_POOL_GET:PROC,RELEASE_EXETABLE_ALL:PROC,RELEASE_BLOCK:PROC,_err_abort:proc,WARN_RET:PROC
		EXTERNDEF	GET_NEW_LOG_BLK:PROC,ALLOC_LOCKED:PROC,_get_omf_name_length_routine:proc,INIT_ARRAY32:PROC
		EXTERNDEF	INIT_PARALLEL_ARRAY:PROC,RELEASE_PARALLEL_ARRAY:PROC,RELEASE_LOCKED:PROC,SKIP_LEAF_SICXAX:PROC
		EXTERNDEF	GET_NAME_HASH32_CASE:PROC

		EXTERNDEF	CVP_UNSUPPORTED_TYPE_ERR:ABS,CVP_PRECOMP_ERR:ABS,CVP_IGNORE_ERR:ABS,CVP_LTYPES_64K_ERR:ABS


CVTYPES_VARS		STRUC

CV_BYTES_LEFT_BP	DD	?
CV_THIS_BLOCK_BP	DD	?
CV_THIS_BLOCK_LIMIT_BP	DD	?
CV_NEXT_BLOCK_BP	DD	?
CV_LF_NULL_PTR_BP	DD	?
CV_FIELDLIST_IN_PTR_BP	DD	?
CV_FIELDLIST_IN_PHYS_BP	DD	?
CV_FIELDLIST_LOG_BP	DD	?
CV_NEXT_VALID_INDEX_BP	DD	?
CV_FIELDLIST_END_BP	DD	?
CV_LOCAL_HASH_PTR_BP	DD	?
CV_LTYPE_LOCAL_HASH_BP	DD	?
CV_MODULE_LTYPE_DELTA_BP	DD	?
CV_LTYPE_LENGTH_BP	DD	?
FIRST_CV_LFINDEX_GINDEX_BP	DD	?
LAST_CV_LFINDEX_GINDEX_BP	DD	?
CV_LF_INDEX_TARGET_BP	DD	?
CV_PUT_LIMIT_BP		DD	?

CVTYPES_VARS		ENDS


FIX	MACRO	X

X	EQU	([EBP-SIZE CVTYPES_VARS].(X&_BP))

	ENDM


FIX	CV_BYTES_LEFT
FIX	CV_THIS_BLOCK
FIX	CV_THIS_BLOCK_LIMIT
FIX	CV_NEXT_BLOCK
FIX	CV_LF_NULL_PTR
FIX	CV_FIELDLIST_IN_PTR
FIX	CV_FIELDLIST_IN_PHYS
FIX	CV_FIELDLIST_LOG
FIX	CV_NEXT_VALID_INDEX
FIX	CV_FIELDLIST_END
FIX	CV_LOCAL_HASH_PTR
FIX	CV_LTYPE_LOCAL_HASH
FIX	CV_MODULE_LTYPE_DELTA
FIX	CV_LTYPE_LENGTH
FIX	FIRST_CV_LFINDEX_GINDEX
FIX	LAST_CV_LFINDEX_GINDEX
FIX	CV_LF_INDEX_TARGET
FIX	CV_PUT_LIMIT


PROCESS_CV_TYPES	PROC
		;
		;CONVERT CV4 TYPES SEGMENT INTO LOCAL INDEXED STRUCTURES
		;
		PUSHM	EBP,EDI,ESI,EBX

		MOV	EBP,ESP
		SUB	ESP,SIZE CVTYPES_VARS
		ASSUME	EBP:PTR CVTYPES_VARS

		CALL	INIT_CV_READER

		CALL	GET_CV_DWORD		;FIRST DWORD MUST BE 1

		JC	L91$

		DEC	EAX
		JNZ	L92$

		MOV	EAX,CV_LTYPE_STRUCT._CV_LTYPE_WORD1	;ALLOCATE NULL TYPE
		CALL	CV_LTYPE_POOL_GET

		MOV	EDI,EAX
		MOV	CV_LF_NULL_PTR,EAX

		XOR	EAX,EAX
		MOV	ECX,CV_LTYPE_STRUCT._CV_LTYPE_LENGTH/4

		MOV	EDX,PRIME_512
		MOV	CV_LOCAL_HASH_PTR,EAX

		MOV	FIRST_CV_LFINDEX_GINDEX,EAX
		MOV	LAST_CV_LFINDEX_GINDEX,EAX

		MOV	CV_LF_INDEX_TARGET,EAX
		MOV	CV_LTYPE_LOCAL_HASH,EDX

		REP	STOSD

		MOV	EDX,I_LF_NULL*64K + 2	;NULL ID AND LENGTH
		MOV	ECX,CV_BYTES_LEFT

		MOV	[EDI],EDX
		JMP	L8$

L92$:
		MOV	AX,CVP_IGNORE_ERR
		CALL	WARN_RET
L91$:
		CALL	RELEASE_EXETABLE_ALL
		JMP	L99$

L1$:
		CALL	GET_TYPE_HEADER

		JC	L92$

		CALL	DO_TYPES_TBL[EAX*4]

		MOV	ECX,CV_BYTES_LEFT
		JC	L92$
		;
		;
		;
		TEST	EAX,EAX
		JZ	L8$

		INSTALL_POINTER_GINDEX	CV_LTYPE_GARRAY
L8$:
		TEST	ECX,ECX
		JNZ	L1$
		;
		;
		;
		MOV	EAX,FIRST_CV_LFINDEX_GINDEX

		OR	EAX,EAX
		JZ	L804$

		CALL	PROCESS_LFINDEXES

L804$:
		SETT	CV_TYPES_VALID
L99$:
		CALL	ADJUST_CV_PTR		;RELEASE CURRENT BLOCK

		MOV	ESP,EBP

		POPM	EBX,ESI,EDI,EBP

		RET

PROCESS_CV_TYPES	ENDP


GET_TYPE_HEADER	PROC	NEAR
		;
		;
		;
		CALL	GET_CV_DWORD		;GET TYPE LENGTH

		MOV	ECX,EAX
		JC	L99$

		SHR	EAX,16
		AND	ECX,0FFFFH

		CMP	ECX,PAGE_SIZE-SIZE CV_LTYPE_STRUCT
		JA	L3$			;TYPE TOO LONG...
		;
		;SOME TYPES NEED SPECIAL HANDLING
		;
		CMP	EAX,17H			;LF_RESERVED
		JB	L29$
L1$:
		SUB	EAX,200H-17H		;LF_SKIP

		CMP	EAX,0DH+17H
		JB	L29$

		SUB	EAX,200H-0DH

		CMP	EAX,0EH+0DH+17H
		JAE	L25$
L29$:
		MOV	EDX,EAX
		MOV	CV_LTYPE_LENGTH,ECX

		SHL	EDX,16

		OR	ECX,EDX

		MOV	DPTR TEMP_RECORD,ECX

		RET

L25$:
		MOV	EAX,I_LF_NOTTRAN
		JMP	L29$

L3$:
		CMP	EAX,LF_FIELDLIST
		JE	L1$

L99$:
		STC

		RET

GET_TYPE_HEADER	ENDP


DO_NORM		PROC	NEAR
		;
		;
		;
		MOV	EAX,CV_LTYPE_LENGTH		;LENGTH

		ADD	EAX,CV_LTYPE_STRUCT._CV_LTYPE_ILEAF
DO_NORM1::
		CALL	CV_LTYPE_POOL_GET		;EAX

		PUSH	EAX
		MOV	EDI,EAX

		MOV	ECX,(CV_LTYPE_STRUCT._CV_LTYPE_LENGTH)/4
		XOR	EAX,EAX

		REP	STOSD			;ZERO OUT HEADER STRUCTURE

		MOV	EDX,DPTR TEMP_RECORD	;LENGTH & ID
		MOV	EAX,CV_LTYPE_LENGTH

		MOV	[EDI],EDX
		ADD	EDI,4

		SUB	EAX,2
		CALL	MOVE_EAX_CV_BYTES

		POP	EAX
		JC	L5$			;ABORT, SOMETHING WRONG

		MOV	ECX,4
		XOR	EDX,EDX

		SUB	ECX,EDI

		AND	ECX,3
		JZ	L5$
L4$:
		MOV	[EDI],DL
		INC	EDI

		DEC	ECX
		JNZ	L4$
L5$:
		RET				;EAX IS ADDRESS

DO_NORM		ENDP


DO_NULL		PROC	NEAR
		;
		;1.  ISSUE WARNING, ILLEGAL TYPE
		;2.  SKIP DATA FOR THIS TYPE
		;3.  RETURN PTR TO AN LF_NULL TYPE
		;
		MOV	AX,CVP_UNSUPPORTED_TYPE_ERR
		CALL	WARN_RET
DO_ENDPRECOMP::
		CALL	MOVE_TO_TEMP_RECORD

		MOV	EAX,CV_LF_NULL_PTR

		RET

DO_NULL		ENDP


MOVE_TO_TEMP_RECORD	PROC	NEAR
		;
		;
		;
		PUSH	EBX
		MOV	EBX,CV_LTYPE_LENGTH

		SUB	EBX,2
		JBE	L99$
L1$:
		MOV	EAX,EBX

		CMP	EAX,MAX_RECORD_LEN-4
		JB	L2$

		MOV	EAX,MAX_RECORD_LEN-4
L2$:
		MOV	EDI,OFF TEMP_RECORD+4
		SUB	EBX,EAX

		CALL	MOVE_EAX_CV_BYTES

		JC	L99$

		TEST	EBX,EBX
		JNZ	L1$
L99$:
		POP	EBX

		RET

MOVE_TO_TEMP_RECORD	ENDP


MOVE_TO_FIELDLIST_IN_PHYS	PROC	NEAR
		;
		;
		;
		PUSH	EBX
		MOV	EBX,CV_LTYPE_LENGTH

		MOV	EDI,CV_FIELDLIST_IN_PHYS
		SUB	EBX,2
		JBE	L99$
L1$:
		MOV	EAX,EBX

		CMP	EAX,PAGE_SIZE-4
		JB	L2$

		MOV	EAX,PAGE_SIZE-4
L2$:
		SUB	EBX,EAX

		CALL	MOVE_EAX_CV_BYTES

		JC	L99$

		TEST	EBX,EBX
		JNZ	L1$
L99$:
		POP	EBX

		RET

MOVE_TO_FIELDLIST_IN_PHYS	ENDP


DO_CLASS	PROC	NEAR
		;
		;HASH NAME
		;ADD TO TABLE FOR FORWARD REFERENCES
		;
		MOV	EAX,CV_LTYPE_LENGTH

		ADD	EAX,CV_LTYPE_STRUCT._CV_LTYPE_ILEAF+4		;IN CASE OF FORWARD REF
		CALL	DO_NORM1

		PUSH	ESI
		JC	L99$

		MOV	ESI,EAX
		ASSUME	ESI:PTR CV_LTYPE_STRUCT
		INSTALL_POINTER_GINDEX	CV_LTYPE_GARRAY

		MOV	ECX,CV_LTYPE_STRUCT._CV_LTYPE_WORD6		;POINT TO VALUE TO SKIP
		PUSH	EAX

		MOV	AL,BPTR [ESI]._CV_LTYPE_WORD3
		MOV	DL,[ESI]._CV_LTYPE_FLAGS

		TEST	AL,80H
		JZ	L2$

		OR	DL,MASK CV_LTYPE_FWDREF
		XOR	EAX,EAX

		MOV	[ESI]._CV_LTYPE_FLAGS,DL
		MOV	DPTR [ESI]._CV_LTYPE_WORD1,EAX

		MOV	[ESI]._CV_LTYPE_WORD5,AX
		MOV	AL,80H

		MOV	DPTR [ESI]._CV_LTYPE_WORD3,EAX

L2$:
DO_CLASS_A::
		MOV	AH,BPTR [ESI+ECX+1]
		ADD	ECX,2

		OR	AH,AH
		JS	L32$
L33$:
DO_CLASS_B::
		MOV	DL,[ESI]._CV_LTYPE_FLAGS
		MOV	[ESI]._CV_LTYPE_NAMEOFF,CL	;SAVE NAME OFFSET

		OR	DL,MASK CV_LTYPE_CSUE

		LEA	EAX,[ESI+ECX]
		MOV	[ESI]._CV_LTYPE_FLAGS,DL
		;
		;ESI+ECX POINTS TO NAME LENGTH
		;
		CALL	GET_NAME_HASH32_CASE		;HASH THE NAME

		MOV	DL,BPTR [ESI]._CV_LTYPE_ILEAF	;MODIFY HASH BY RECORD TYPE...
		POP	ECX				;LTYPE_GINDEX

		XOR	AL,DL
		MOV	DL,[ESI]._CV_LTYPE_FLAGS

		;
		;DX:AX IS HASH, BX IS LTYPE_GINDEX, DS:SI PTS.
		;
		AND	DL,MASK CV_LTYPE_FWDREF
		JZ	L6$
		;
		;FORWARD REFERENCE, INSTALL IT SO A NON-FORWARD CAN UPDATE IT LATER
		;
		MOV	[ESI]._CV_LTYPE_HASH,EAX
		CALL	INSTALL_LOCAL_FWD		;PUT IN LOCAL TABLE

		XOR	EAX,EAX
L99$:
		POP	ESI

		RET


L32$:
		MOV	AL,BPTR [ESI+ECX-2]
		CALL	SKIP_LEAF_SICXAX

		JMP	L33$

L6$:
		;
		;THIS IS DEFINED.  SEE IF A PREVIOUS FORWARD REFERENCE MADE
		;
		MOV	[ESI]._CV_LTYPE_HASH,EAX
		CALL	SEARCH_LOCAL_FWD

		MOV	ECX,CV_LTYPE_LENGTH
		JNZ	L7$
		;
		;COPY THIS DEFINITION OVER OLD	ES:DI POINTS TO OLD
		;
		ADD	ECX,CV_LTYPE_STRUCT._CV_LTYPE_ILEAF+3

		SHR	ECX,2

		REP	MOVSD
L7$:
		XOR	EAX,EAX
		POP	ESI

		RET

DO_CLASS	ENDP


DO_UNION	PROC	NEAR
		;
		;
		;
		MOV	EAX,CV_LTYPE_LENGTH

		ADD	EAX,CV_LTYPE_STRUCT._CV_LTYPE_ILEAF+4		;IN CASE OF FORWARD REF
		CALL	DO_NORM1

		PUSH	ESI
		JC	L99$

		MOV	ESI,EAX
		INSTALL_POINTER_GINDEX	CV_LTYPE_GARRAY
		ASSUME	ESI:PTR CV_LTYPE_STRUCT

		MOV	ECX,CV_LTYPE_STRUCT._CV_LTYPE_WORD4		;POINT TO VALUE TO SKIP
		PUSH	EAX						;SAVE GINDEX

		MOV	AL,BPTR [ESI]._CV_LTYPE_WORD3
		MOV	DL,[ESI]._CV_LTYPE_FLAGS

		TEST	AL,80H
		JZ	L2$

		XOR	EAX,EAX
		OR	DL,MASK CV_LTYPE_FWDREF

		MOV	DPTR [ESI]._CV_LTYPE_WORD1,EAX
		MOV	AL,80H

		MOV	[ESI]._CV_LTYPE_FLAGS,DL

		MOV	[ESI]._CV_LTYPE_WORD3,AX
L2$:
		JMP	DO_CLASS_A

L99$:
		POP	ESI

		RET

DO_UNION	ENDP


DO_ENUM		PROC	NEAR
		;
		;
		;
		MOV	EAX,CV_LTYPE_LENGTH

		ADD	EAX,CV_LTYPE_STRUCT._CV_LTYPE_ILEAF+4		;IN CASE OF FORWARD REF
		CALL	DO_NORM1

		PUSH	ESI
		JC	L99$

		MOV	ESI,EAX
		ASSUME	ESI:PTR CV_LTYPE_STRUCT
		INSTALL_POINTER_GINDEX	CV_LTYPE_GARRAY

		MOV	ECX,CV_LTYPE_STRUCT._CV_LTYPE_WORD5		;POINT TO NAME
		PUSH	EAX

		MOV	AL,BPTR [ESI]._CV_LTYPE_WORD4
		MOV	DL,[ESI]._CV_LTYPE_FLAGS

		TEST	AL,80H
		JZ	L2$

		XOR	EAX,EAX
		OR	DL,MASK CV_LTYPE_FWDREF

		MOV	DPTR [ESI]._CV_LTYPE_WORD1,EAX
		MOV	EAX,800000H

		MOV	[ESI]._CV_LTYPE_FLAGS,DL
		MOV	DPTR [ESI]._CV_LTYPE_WORD3,EAX
L2$:
		JMP	DO_CLASS_B

L99$:
		POP	ESI

		RET


		ASSUME	ESI:NOTHING

DO_ENUM		ENDP


DO_PRECOMP	PROC	NEAR
		;
		;
		;
		MOV	AX,CVP_PRECOMP_ERR
		CALL	WARN_RET

		CALL	MOVE_TO_TEMP_RECORD

		XOR	EAX,EAX

		MOV	AX,WPTR TEMP_RECORD+6
		JMP	DO_SKIP_EAX

DO_PRECOMP	ENDP


DO_SKIP		PROC	NEAR
		;
		;
		;
		MOV	EAX,CV_LTYPE_LENGTH

		CMP	EAX,4
		JB	L99$

		SUB	EAX,2

		MOV	CV_LTYPE_LENGTH,EAX
		CALL	GET_CV_WORD	;NEXT INDEX

		JC	L99$

		PUSH	EAX
		CALL	MOVE_TO_TEMP_RECORD	;THROW AWAY SKIP RECORD

		POP	EAX
		JC	L99$

		SUB	EAX,CV_LTYPE_GARRAY._STD_LIMIT	;NUMBER TO SKIP
		JA	DO_SKIP_EAX
L99$:
		STC

		RET

DO_SKIP		ENDP


DO_SKIP_EAX	PROC	NEAR
		;
		;SKIP EAX-1 TYPES (ONE IS NULLED UPON RETURN)
		;
		SUB	EAX,1
		JBE	L9$

		MOV	ECX,EAX
L1$:
		MOV	EAX,CV_LF_NULL_PTR
		INSTALL_POINTER_GINDEX	CV_LTYPE_GARRAY

		DEC	ECX
		JNZ	L1$
L9$:
		MOV	EAX,CV_LF_NULL_PTR

		RET

DO_SKIP_EAX	ENDP


DO_FIELDLIST	PROC	NEAR
		;
		;1. REMOVE ALIGNMENT JUNK, ADD IT BACK IN
		;2. ADD LF_INDEX RECORDS ONTO THIS ONE
		;
		MOV	EAX,CV_LTYPE_LENGTH
		MOV	EDX,CV_LTYPE_GARRAY._STD_LIMIT

		CMP	EAX,PAGE_SIZE-8
                JA	SPECIAL_ALLOC

		CALL	GET_NEW_LOG_BLK		;THIS IS WHERE WE BUILD THE FINAL FIELDLIST RECORD

		PUSH	EDI
		ADD	EDX,1000H

		MOV	EDI,EAX
		ADD	EAX,PAGE_SIZE-2

		MOV	CV_PUT_LIMIT,EAX
		CALL	GET_NEW_LOG_BLK		;TO BUFFER POSSIBLY LONG INPUT RECORD
L0$:
		MOV	CV_FIELDLIST_LOG,EDI
		MOV	CV_FIELDLIST_IN_PHYS,EAX

		MOV	CV_NEXT_VALID_INDEX,EDX
		MOV	EAX,I_LF_FIELDLIST SHL 16

		MOV	[EDI],EAX
		ADD	EDI,4

;		MOV	EAX,CV_LTYPE_LENGTH
		PUSH	EDI

;		CMP	EAX,PAGE_SIZE-8
;		JA	L98$

		CALL	MOVE_TO_FIELDLIST_IN_PHYS	;MOVE STUFF TO TEMP RECORD

		MOV	EAX,CV_LTYPE_LENGTH
		JC	L98$

		MOV	CV_FIELDLIST_IN_PTR,ESI
		MOV	ESI,CV_FIELDLIST_IN_PHYS

		ADD	EAX,ESI
		POP	EDI

		SUB	EAX,2

		MOV	CV_FIELDLIST_END,EAX
		JMP	L3$

SPECIAL_ALLOC:
		ADD	EAX,EAX
		;THIS IS WHERE WE BUILD THE FINAL FIELDLIST RECORD
		push	EDX
		push	ECX
		push	EAX
		call	_get_large_segment
		add	ESP,4
		pop	ECX
		pop	EDX

		PUSH	EDI
		ADD	EDX,1000H

		MOV	EDI,EAX
		ADD	EAX,CV_LTYPE_LENGTH
		ADD	EAX,CV_LTYPE_LENGTH
                SUB	EAX,2

		MOV	CV_PUT_LIMIT,EAX
		MOV	EAX,CV_LTYPE_LENGTH
		;TO BUFFER POSSIBLY LONG INPUT RECORD
		push	EDX
		push	ECX
		push	EAX
		call	_get_large_segment
		add	ESP,4
		pop	ECX
		pop	EDX
                JMP	L0$

L98$:
		POP	EAX
L99$:
		POP	EDI

                CALL	RELEASE_FL_TEMPS

		STC
		RET

L11$:
		MOV	AL,[ESI]
L12$:
		MOV	AH,[ESI+1]
		ADD	ESI,2

		MOV	EDX,CV_PUT_LIMIT
		AND	EAX,0FFFFH

		CMP	EDI,EDX
		JA	L99$

		MOV	[EDI],EAX		;DWORD ALIGNED...
		SUB	AH,4

		ADD	EDI,2
		XOR	ECX,ECX

		CMP	EAX,0DH
		JA	L99$

		CALL	FIELDLIST_TBL[EAX*4]	;RETURNS ECX = # OF BYTES TO MOVE TO ES:DI

		MOV	EAX,ECX
		JC	L99$
		;
		;
		;
		TEST	ECX,ECX
		JZ	L15$

		ADD	EAX,EDI
		MOV	EDX,CV_PUT_LIMIT

		CMP	EAX,EDX
		JA	L99$

		OPTI_MOVSB
L15$:
		;
		;ALIGN OUTPUT TO DWORD BOUNDARY
		;
		XOR	EAX,EAX

		SUB	EAX,EDI

		AND	EAX,3
		JZ	L3$

		MOV	ECX,EAX
		OR	AL,0F0H
L2$:
		MOV	[EDI],AL
		INC	EDI

		DEC	EAX
		DEC	ECX

		JNZ	L2$

L3$:
		;
		;SEE IF END OF INPUT SIDE...
		;
		MOV	EDX,CV_FIELDLIST_END
		MOV	AL,[ESI]

		CMP	ESI,EDX
		JAE	L5$

		CMP	AL,0F0H
		JBE	L12$

		AND	EAX,0FH

		ADD	ESI,EAX

		CMP	ESI,EDX
		JB	L11$
L5$:
		;
		;NOW OUTPUT AS A SINGLE FIELDLIST RECORD
		;
		MOV	ESI,CV_FIELDLIST_LOG
		MOV	EAX,CV_LTYPE_STRUCT._CV_LTYPE_ILEAF

		SUB	EDI,ESI

		MOV	ECX,EDI
		SUB	EDI,2

		ADD	EAX,EDI
		OR	EDI,I_LF_FIELDLIST SHL 16

		MOV	[ESI],EDI

		CALL	CV_LTYPE_POOL_GET

		ADD	ECX,2
		PUSHM	EAX

		SHR	ECX,2
		MOV	EBX,EAX

		PUSH	ECX
		MOV	EDI,EAX

		MOV	ECX,(CV_LTYPE_STRUCT._CV_LTYPE_LENGTH)/4
		XOR	EAX,EAX

		REP	STOSD			;ZERO OUT HEADER STRUCTURE

		POP	ECX
		MOV	EAX,CV_LF_INDEX_TARGET

		REP	MOVSD
		;
		;IF NON-CONTIGUOUS LF_INDEX, ADD TO LINKED LIST
		;
		OR	EAX,EAX
		JZ	L58$

		MOV	ECX,CV_LTYPE_GARRAY._STD_LIMIT
		MOV	[EBX].CV_LTYPE_STRUCT._CV_LTYPE_INDEX_TARGET,EAX

		XOR	EAX,EAX
		INC	ECX

		MOV	CV_LF_INDEX_TARGET,EAX
		MOV	EAX,LAST_CV_LFINDEX_GINDEX

		TEST	EAX,EAX
		JZ	L53$

		CONVERT	ESI,EAX,CV_LTYPE_GARRAY
		ASSUME	ESI:PTR CV_LTYPE_STRUCT

		MOV	[ESI]._CV_LTYPE_NEXT_LFINDEX,ECX
L57$:
		MOV	LAST_CV_LFINDEX_GINDEX,ECX
L58$:
		;
		;AND SKIP ANY HOLES CREATED BY LF_INDEX RECORDS
		;
		MOV	EAX,CV_NEXT_VALID_INDEX
		MOV	EDX,CV_LTYPE_GARRAY._STD_LIMIT

		SUB	EAX,EDX

		SUB	EAX,1000H
		JZ	L7$

		MOV	ECX,EAX
L6$:
		POP	EAX

		INSTALL_POINTER_GINDEX	CV_LTYPE_GARRAY

		MOV	EAX,CV_LF_NULL_PTR
		DEC	ECX

		PUSH	EAX
		JNZ	L6$
L7$:
                CALL	RELEASE_FL_TEMPS

		MOV	ESI,CV_FIELDLIST_IN_PTR
		POP	EAX

		OR	ECX,ECX
		POP	EDI

		RET

L53$:
		MOV	FIRST_CV_LFINDEX_GINDEX,ECX
		JMP	L57$

		ASSUME	ESI:NOTHING

DO_FIELDLIST	ENDP


FL_4_VAL	PROC	NEAR
		;
		;
		;
		MOV	AH,[ESI+5]
		MOV	CL,6

		OR	AH,AH
		JS	L5$

		RET

L5$:
		MOV	AL,[ESI+4]
		JMP	SKIP_LEAF_SICXAX

FL_4_VAL	ENDP


FL_6_VAL_VAL	PROC	NEAR
		;
		;
		;
		MOV	AH,[ESI+7]
		MOV	CL,8

		OR	AH,AH
		JS	L5$
L1$:
		MOV	AH,[ESI+ECX+1]
		ADD	ECX,2

		OR	AH,AH
		JS	L6$

		RET

L5$:
		MOV	AL,[ESI+6]
		CALL	SKIP_LEAF_SICXAX

		JMP	L1$

L6$:
		MOV	AL,[ESI+ECX-2]
		JMP	SKIP_LEAF_SICXAX

FL_6_VAL_VAL	ENDP


FL_2		PROC	NEAR
		;
		;JUST COPY 2 MORE BYTES
		;
		OR	EAX,EAX
		MOV	CL,2

		RET

FL_2		ENDP


FL_6		PROC	NEAR
		;
		;JUST COPY 6 BYTES
		;
		OR	EAX,EAX
		MOV	CL,6

		RET

FL_6		ENDP


FL_2_VAL_NAM	PROC	NEAR
		;
		;
		;
		MOV	AH,[ESI+3]
		MOV	CL,4

		OR	AH,AH
		JNS	FL_2_NAM_CONT

		MOV	AL,[ESI+2]
		CALL	SKIP_LEAF_SICXAX

		JMP	FL_2_NAM_CONT

FL_2_VAL_NAM	ENDP


FL_4_VAL_NAM	PROC	NEAR
		;
		;
		;
		MOV	AH,[ESI+5]
		MOV	CL,6

		OR	AH,AH
		JNS	FL_2_NAM_CONT

		MOV	AL,[ESI+4]
		CALL	SKIP_LEAF_SICXAX

		JMP	FL_2_NAM_CONT

FL_4_VAL_NAM	ENDP


FL_8_NAM	PROC	NEAR

		MOV	CL,8
		JMP	FL_2_NAM_CONT

FL_8_NAM	ENDP


FL_4_NAM	PROC	NEAR

		MOV	CL,4
		JMP	FL_2_NAM_CONT

FL_4_NAM	ENDP


FL_2_NAM	PROC	NEAR
		;
		;2 BYTES PLUS A NAME
		;
		MOV	CL,2
FL_2_NAM_CONT::
		MOV	EDX,ESI

		ADD	ESI,ECX

		GET_OMF_NAME_LENGTH

		LEA	ECX,[ESI+EAX]
		MOV	ESI,EDX

		SUB	ECX,EDX

		RET

FL_2_NAM	ENDP


FL_INDEX	PROC	NEAR
		;
		;THIS REFERENCES ANOTHER LIST OF FIELDS
		;
		MOV	CX,[ESI]
		MOV	EAX,CV_NEXT_VALID_INDEX

		CMP	EAX,ECX
		JNZ	L98$
		;
		;OK, GET SET UP TO READ IN ANOTHER RECORD
		;
		PUSH	EDI
		MOV	ESI,CV_FIELDLIST_IN_PTR

		CALL	GET_TYPE_HEADER

		MOV	ECX,CV_LTYPE_LENGTH
		JC	L99$

		CMP	AL,I_LF_FIELDLIST
		JNZ	L99$

		CMP	ECX,PAGE_SIZE-8
		JA	L99$

		MOV	EAX,ECX
		PUSH	ECX

		CALL	MOVE_TO_FIELDLIST_IN_PHYS	;MOVE STUFF TO TEMP RECORD

		POP	ECX
		JC	L99$

		MOV	CV_FIELDLIST_IN_PTR,ESI
		MOV	EAX,CV_NEXT_VALID_INDEX

		MOV	ESI,CV_FIELDLIST_IN_PHYS
		INC	EAX

		ADD	ECX,ESI
		POP	EDI

		MOV	CV_NEXT_VALID_INDEX,EAX
		SUB	ECX,2

		MOV	CV_FIELDLIST_END,ECX
		XOR	ECX,ECX			;DON'T MOVE ANY BYTES

		SUB	EDI,2

		RET

L98$:
		;
		;HMM, LINK TO ANOTHER NON-CONTIGUOUS RECORD...
		;
		ADD	ESI,2
		MOV	CV_LF_INDEX_TARGET,ECX

		XOR	ECX,ECX			;DON'T MOVE ANY BYTES
		SUB	EDI,2			;DELETE LF_INDEX

		RET

L99$:
		MOV	AL,0
		push	EAX
		call	_err_abort

		STC
		RET

FL_INDEX	ENDP


RELEASE_FL_TEMPS PROC	NEAR

		MOV	EAX,CV_FIELDLIST_LOG
                CMP	CV_LTYPE_LENGTH,PAGE_SIZE-8
                JA	L1$

		CALL	RELEASE_BLOCK

		MOV	EAX,CV_FIELDLIST_IN_PHYS
		JMP	RELEASE_BLOCK

L1$:
		PUSHM	EDX,ECX
		push	EAX
		call	_release_large_segment
		add	ESP,4
		POPM	ECX,EDX

		MOV	EAX,CV_FIELDLIST_IN_PHYS

		PUSHM	EDX,ECX
		push	EAX
		call	_release_large_segment
		add	ESP,4
		POPM	ECX,EDX

		ret

RELEASE_FL_TEMPS ENDP

		ASSUME	ESI:NOTHING

INIT_CV_READER	PROC	NEAR	PRIVATE
		;
		;SET UP STUFF FOR SCANNING THROUGH A CODEVIEW SEGMENT
		;
		MOV	EAX,FIX2_SM_LEN
		XOR	ECX,ECX

		MOV	CV_BYTES_LEFT,EAX
		MOV	EAX,OFF EXETABLE

		MOV	CV_THIS_BLOCK,ECX
		MOV	CV_NEXT_BLOCK,EAX

;		CALL	ADJUST_CV_PTR
;		RET

INIT_CV_READER	ENDP


ADJUST_CV_PTR	PROC	NEAR	PRIVATE
		;
		;
		;
		XOR	ECX,ECX
		MOV	EAX,CV_THIS_BLOCK

		MOV	CV_THIS_BLOCK,ECX
		MOV	EDX,CV_NEXT_BLOCK

		TEST	EAX,EAX
		JZ	L1$

		CALL	RELEASE_BLOCK
L1$:
		MOV	EAX,[EDX]
		MOV	[EDX],ECX

		ADD	EDX,4
		MOV	CV_THIS_BLOCK,EAX

		OR	EAX,EAX
		JZ	L9$

		MOV	ESI,EAX
		ADD	EAX,PAGE_SIZE

		MOV	CV_NEXT_BLOCK,EDX
		MOV	CV_THIS_BLOCK_LIMIT,EAX

		RET

L9$:
		STC

		RET

ADJUST_CV_PTR	ENDP


GET_CV_DWORD	PROC	NEAR	PRIVATE
		;
		;
		;
		ADD	ESI,4
		MOV	ECX,CV_BYTES_LEFT

		MOV	EAX,CV_THIS_BLOCK_LIMIT
		SUB	ECX,4

		CMP	EAX,ESI
		JB	L5$

		MOV	CV_BYTES_LEFT,ECX
		MOV	EAX,[ESI-4]

		RET

L5$:
		SUB	ESI,4
		CALL	GET_CV_WORD

		JC	L9$

		PUSH	EAX
		CALL	GET_CV_WORD

		POP	EDX
		JC	L9$

		SHL	EAX,16
		AND	EDX,0FFFFH

		OR	EAX,EDX

		RET


L9$:
		MOV	AL,-1

		RET

GET_CV_DWORD	ENDP


GET_CV_WORD	PROC	NEAR	PRIVATE
		;
		;
		;
		ADD	ESI,2
		MOV	EAX,CV_THIS_BLOCK_LIMIT

		CMP	EAX,ESI
		JB	L5$

		XOR	EAX,EAX
		MOV	ECX,CV_BYTES_LEFT

		MOV	AL,[ESI-2]
		SUB	ECX,2

		MOV	AH,[ESI-1]
		MOV	CV_BYTES_LEFT,ECX
L9$:
		RET

L5$:
		SUB	ESI,2
		CALL	GET_CV_BYTE

		JC	L9$

		PUSH	EAX
		CALL	GET_CV_BYTE

		MOV	AH,AL
		JC	L99$

		AND	EAX,0FFFFH
L99$:
		POP	EDX

		MOV	AL,DL

		RET

GET_CV_WORD	ENDP


GET_CV_BYTE	PROC	NEAR	PRIVATE
		;
		;
		;
L1$:
		INC	ESI
		MOV	ECX,CV_BYTES_LEFT

		MOV	EAX,CV_THIS_BLOCK_LIMIT
		DEC	ECX

		CMP	EAX,ESI
		JB	L5$

		MOV	CV_BYTES_LEFT,ECX
		MOV	AL,[ESI-1]

		RET

L5$:
		DEC	ESI
		CALL	ADJUST_CV_PTR

		JNC	L1$

		RET

GET_CV_BYTE	ENDP


MOVE_EAX_CV_BYTES	PROC	NEAR	PRIVATE
		;
		;NEED TO MOVE SMALLER OF EAX AND PAGE_SIZE-SI
		;
		MOV	ECX,CV_THIS_BLOCK_LIMIT
		MOV	EDX,CV_BYTES_LEFT

		SUB	ECX,ESI
		SUB	EDX,EAX

		MOV	CV_BYTES_LEFT,EDX
		JC	L9$
L1$:
		SUB	EAX,ECX
		JA	L5$

		ADD	ECX,EAX
		XOR	EAX,EAX
L5$:
		OPTI_MOVSB

		OR	EAX,EAX
		JNZ	L3$
L9$:
		RET

L3$:
		;
		;GET NEXT BLOCK
		;
		PUSH	EAX
		CALL	ADJUST_CV_PTR

		POP	EAX
		MOV	ECX,PAGE_SIZE

		JNC	L1$

		RET

MOVE_EAX_CV_BYTES	ENDP


SEARCH_LOCAL_FWD	PROC	NEAR
		;
		;IS THIS GUY IN FORWARD REFERENCE TABLE?
		;
		;EAX IS HASH
		;ECX IS LTYPE_GINDEX
		;ESI IS POINTER
		;
		ASSUME	ESI:PTR CV_LTYPE_STRUCT

		MOV	EDI,CV_LOCAL_HASH_PTR
		MOV	ECX,EAX

		TEST	EDI,EDI
		JZ	L9$

		XOR	EDX,EDX

		HASHDIV	CV_LTYPE_LOCAL_HASH

		MOV	EDI,[EDI+EDX*4]
		ASSUME	EDI:PTR CV_LFWD_STRUCT
L2$:
		TEST	EDI,EDI
		JZ	L8$
L3$:
		MOV	EDX,[EDI]._CV_LFWD_HASH
		MOV	EAX,[EDI]._CV_LFWD_GINDEX

		MOV	EDI,[EDI]._CV_LFWD_NEXT_HASH
		CMP	EDX,ECX

		JNZ	L2$
		;
		;PROBABLE MATCH, DO NAME COMPARE
		;
		PUSHM	EDI,ECX

		CONVERT	ECX,EAX,CV_LTYPE_GARRAY
		ASSUME	ECX:PTR CV_LTYPE_STRUCT

		XOR	EAX,EAX
		PUSH	ESI

		MOV	AL,[ECX]._CV_LTYPE_NAMEOFF
		MOV	EDI,ECX

		ADD	EDI,EAX
		MOV	AL,[ESI]._CV_LTYPE_NAMEOFF

		MOV	EDX,ECX
		ADD	ESI,EAX

		GET_OMF_NAME_LENGTH

		MOV	ECX,EAX
		ASSUME	ECX:NOTHING

		push	ECX
		push	EDX
		push	EDI
		mov	EAX,ESP
		push	EAX
		call	_get_omf_name_length_routine
		add	ESP,4
		pop	EDI
		pop	EDX
		pop	ECX
;		CALL	GET_OMF_NAME_LENGTH_EDI

		CMP	ECX,EAX
		JNZ	L5$

		REPE	CMPSB

		POP	ESI
		JNZ	L5$
		;
		;MATCH,RETURN HASH IN DX:AX, POINTER IN ES:DI
		;
		MOV	EDI,EDX
		POP	EAX

		POPM	EDX

		RET

L5$:
		;
		;FAILED
		;
		POPM	ECX,EDI

		TEST	EDI,EDI
		JNZ	L3$
L8$:
L9$:
		OR	AL,-1

		RET

		ASSUME	EDI:NOTHING,ESI:NOTHING

SEARCH_LOCAL_FWD	ENDP


INSTALL_LOCAL_FWD	PROC	NEAR
		;
		;THIS IS A FORWARD REFERENCE, INSTALL IN TABLE SO I CAN
		;QUICKLY FIND IT LATER
		;
		;EAX IS HASH
		;ECX IS LTYPE_GINDEX
		;ESI IS POINTER
		;
		ASSUME	ESI:PTR CV_LTYPE_STRUCT

		PUSH	EDI
		MOV	EDI,CV_LOCAL_HASH_PTR

		TEST	EDI,EDI
		JZ	L1$
		;
		;I DON'T CARE ABOUT SEARCHING, SHOULD ONLY BE ONE PER MODULE..
		;
L2$:
		PUSH	EAX
		XOR	EDX,EDX

		HASHDIV	CV_LTYPE_LOCAL_HASH

		MOV	EAX,SIZE CV_LFWD_STRUCT
		CALL	CV_LTYPE_POOL_GET
		ASSUME	EAX:PTR CV_LFWD_STRUCT

		MOV	[EAX]._CV_LFWD_GINDEX,ECX
		MOV	ECX,[EDI+EDX*4]

		MOV	[EDI+EDX*4],EAX
		MOV	[EAX]._CV_LFWD_NEXT_HASH,ECX

		POPM	ECX,EDI

		MOV	[EAX]._CV_LFWD_HASH,ECX

		RET

L1$:
		PUSHM	ECX,EAX

		MOV	EAX,PRIME_512*4
		CALL	CV_LTYPE_POOL_GET

		MOV	CV_LOCAL_HASH_PTR,EAX
		MOV	EDI,EAX

		MOV	ECX,PRIME_512
		XOR	EAX,EAX

		REP	STOSD

		POPM	EAX,ECX

		MOV	EDI,CV_LOCAL_HASH_PTR
		JMP	L2$

		ASSUME	EAX:NOTHING,ESI:NOTHING

INSTALL_LOCAL_FWD	ENDP


PROCESS_LFINDEXES	PROC	NEAR
		;
		;THERE ARE SOME OUT-OF-ORDER LF_INDEX RECORDS.  NEED TO PROCESS THEM
		;
		PUSHM	EDI,ESI,EBX
L1$:
		CONVERT	ESI,EAX,CV_LTYPE_GARRAY
		ASSUME	ESI:PTR CV_LTYPE_STRUCT

		MOV	EDX,EAX
		XOR	ECX,ECX

		MOV	EAX,[ESI]._CV_LTYPE_NEXT_LFINDEX
		MOV	[ESI]._CV_LTYPE_NEXT_LFINDEX,ECX		;UNLINK FROM LIST

		MOV	EBX,[ESI]._CV_LTYPE_INDEX_TARGET
		PUSH	EAX

		OR	EBX,EBX
		JZ	L9$
		;
		;THIS LTYPE POINTS TO MORE...  ADD UP SIZES PLEASE
		;
		PUSH	EDX			;STARTING GINDEX
		XOR	EDX,EDX			;SIZE SO FAR...

L2$:
		MOV	ECX,DPTR [ESI]._CV_LTYPE_LENGTH
		MOV	EAX,[ESI]._CV_LTYPE_INDEX_TARGET

		AND	ECX,0FFFFH
		SUB	EDX,2			;DON'T NEED EXTRA ILEAFS

		ADD	EDX,ECX
		OR	EAX,EAX

		JZ	L3$

		SUB	EAX,1000H-1
		CONVERT	ESI,EAX,CV_LTYPE_GARRAY

		JMP	L2$

L3$:
		;
		;EDX IS LENGTH OF FIELDLIST...
		;
		;ALLOCATE SPACE
		;
		LEA	EAX,[EDX+CV_LTYPE_STRUCT._CV_LTYPE_ILEAF+2]
		ADD	EDX,2

		POP	ECX			;ORIGINAL GINDEX
		CALL	CV_LTYPE_POOL_GET

		PUSHM	ECX,EAX
		;
		;COPY FIRST HEADER
		;
		MOV	EDI,EAX
		CONVERT	ESI,ECX,CV_LTYPE_GARRAY

		MOV	EBX,ESI
		MOV	ECX,(CV_LTYPE_STRUCT._CV_LTYPE_ILEAF+2)/4

		REP	MOVSD

		MOV	WPTR [EDI-4],DX
		MOV	ESI,EBX
		;
		;START BACK AT BEGINNING, COPY THESE OLD TYPES INTO NEW ONE, ZEROING POINTERS
		;
L4$:
		MOV	ECX,DPTR [ESI]._CV_LTYPE_LENGTH
		XOR	EAX,EAX

		AND	ECX,0FFFFH
		MOV	EDX,[ESI]._CV_LTYPE_INDEX_TARGET

		SUB	ECX,2			;DON'T MOVE ILEAF
		MOV	[ESI]._CV_LTYPE_INDEX_TARGET,EAX

		LEA	ESI,[ESI]._CV_LTYPE_WORD1

		OPTI_MOVSB

		OR	EDX,EDX
		JZ	L5$

		SUB	EDX,1000H-1
		CONVERT	ESI,EDX,CV_LTYPE_GARRAY

		JMP	L4$

L5$:
		;
		;NOW STORE THIS AS ORIGINAL GINDEX POINTER
		;
		POPM	EAX,ECX
		INSTALL_POINTER_RANDOM_GINDEX	CV_LTYPE_GARRAY

L9$:
		POP	EAX

		OR	EAX,EAX
		JNZ	L1$

		POPM	EBX,ESI,EDI

		RET

PROCESS_LFINDEXES	ENDP


INSTALL_LTYPE_POINTER	PROC
		;
		;EAX IS POINTER, RETURN GINDEX #
		;

		PUSH	EDX
		MOV	EDX,CV_LTYPE_GARRAY._STD_LIMIT

		SHR	EDX,PAGE_BITS-2
		PUSH	ECX

		MOV	ECX,CV_LTYPE_GARRAY._STD_LIMIT

		MOV	EDX,CV_LTYPE_GARRAY[EDX*4]._STD_PTRS
		AND	ECX,PAGE_MASK SHR 2

		TEST	EDX,EDX
		JZ	L3$
L4$:
		MOV	[EDX+ECX*4],EAX
		MOV	EAX,CV_LTYPE_GARRAY._STD_LIMIT

		POP	ECX
		INC	EAX

		POP	EDX
		MOV	CV_LTYPE_GARRAY._STD_LIMIT,EAX

		CMP	EAX,64K - 1000H
		JA	L9$

		RET

L3$:
		MOV	EDX,CV_LTYPE_GARRAY._STD_LIMIT
		PUSH	EAX

		SHR	EDX,PAGE_BITS-2
		CALL	GET_NEW_LOG_BLK

		MOV	CV_LTYPE_GARRAY[EDX*4]._STD_PTRS,EAX
		MOV	EDX,EAX

		POP	EAX
		JMP	L4$

L9$:
		MOV	AX,CVP_LTYPES_64K_ERR
		push	EAX
		call	_err_abort

INSTALL_LTYPE_POINTER	ENDP


		.DATA

		ALIGN	4

DO_TYPES_TBL	LABEL	DWORD

		DD	DO_NULL		;LF_UNDEFINED
		DD	DO_NORM		;LF_MODIFIER
		DD	DO_NORM		;LF_POINTER
		DD	DO_NORM		;LF_ARRAY
		DD	DO_CLASS	;LF_CLASS
		DD	DO_CLASS	;LF_STRUCTURE
		DD	DO_UNION	;LF_UNION
		DD	DO_ENUM		;LF_ENUM
		DD	DO_NORM		;LF_PROCEDURE
		DD	DO_NORM		;LF_MFUNCTION
		DD	DO_NORM		;LF_VTSHAPE
		DD	DO_NORM		;LF_COBOL0
		DD	DO_NORM		;LF_COBOL1
		DD	DO_NORM		;LF_BARRAY
		DD	DO_NORM		;LF_LABEL
		DD	DO_NORM		;LF_NULL
		DD	DO_NULL		;LF_NOTTRAN
		DD	DO_NORM		;LF_DIMARRAY
		DD	DO_NORM		;LF_VFTPATH
		DD	DO_PRECOMP	;LF_PRECOMP
		DD	DO_ENDPRECOMP	;LF_ENDPRECOMP
		DD	DO_NORM		;LF_OEM
		DD	DO_NULL		;LF_RESERVED
		DD	DO_SKIP		;LF_SKIP
		DD	DO_NORM		;LF_ARGLIST
		DD	DO_NORM		;LF_DEFARG
		DD	DO_NULL		;LF_LIST
		DD	DO_FIELDLIST	;LF_FIELDLIST
		DD	DO_NULL		;LF_DERIVED
		DD	DO_NORM		;LF_BITFIELD
		DD	DO_NORM		;LF_METHODLIST
		DD	DO_NORM		;LF_DIMCONU
		DD	DO_NORM		;LF_DIMCONLU
		DD	DO_NORM		;LF_DIMVARU
		DD	DO_NORM		;LF_DIMVARLU
		DD	DO_NORM		;LF_REFSYM
		DD	DO_NORM		;LF_BCLASS
		DD	DO_NORM		;LF_VBCLASS
		DD	DO_NORM		;LF_IVBCLASS
		DD	DO_NORM		;LF_ENUMERATE
		DD	DO_NORM		;LF_FRIENDFCN
		DD	DO_NULL		;LF_INDEX
		DD	DO_NORM		;LF_MEMBER
		DD	DO_NORM		;LF_NESTTYPE
		DD	DO_NORM		;LF_VFUNCTAB
		DD	DO_NORM		;LF_FRIENDCLS
		DD	DO_NORM		;LF_ONEMETHOD
		DD	DO_NORM		;LF_VFUNCOFF


		ALIGN	4

FIELDLIST_TBL	LABEL	DWORD

		DD	FL_4_VAL		;BCLASS
		DD	FL_6_VAL_VAL		;VBCLASS
		DD	FL_6_VAL_VAL		;IVBCLASS
		DD	FL_2_VAL_NAM		;ENUMERATE
		DD	FL_2_NAM		;FRIENDFCN
		DD	FL_INDEX		;INDEX
		DD	FL_4_VAL_NAM		;MEMBER
		DD	FL_4_NAM		;STMEMBER
		DD	FL_4_NAM		;METHOD
		DD	FL_2_NAM		;NESTEDTYPE
		DD	FL_2			;VFUNCTAB
		DD	FL_2			;FRIENDCLS
		DD	FL_8_NAM		;ONEMETHOD
		DD	FL_6			;VFUNCOFF

endif


		END

